/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import common.GeneralHandling;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.cassandra.thrift.*;
import org.apache.thrift.TException;
import pojo.Counter;
import pojo.Status;
import pojo.Tag;
import pojo.User;

/**
 *
 * @author tipuder
 */
public class CounterDAO {
    private static Cassandra.Client client;
    private static CounterDAO instance;

    public static CounterDAO getInstance(Cassandra.Client _client)
    {
        if (instance != null)
            return instance;
        instance = new CounterDAO();
        client = _client;
        return instance;
    }

    public static int getCounterStatus(Cassandra.Client cl)
    {
        int result = 0;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Counter.key_status);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            result = common.GeneralHandling.toInt(counterCol.value);
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }    
    
    public static String getCounterStatusString(Cassandra.Client cl)
    {
        String result = "0";
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Counter.key_status);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            result = common.GeneralHandling.toString(counterCol.value);
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
 
    public static String getCounterTagString(Cassandra.Client cl)
    {
        String result = "0";
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Counter.key_tag);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            result = common.GeneralHandling.toString(counterCol.value);
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }      

    public static int getCounterTag(Cassandra.Client cl)
    {
        int result = 0;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(Counter.key_tag);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            result = common.GeneralHandling.toInt(counterCol.value);
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }  
    
    public boolean setCounter(Counter counter)
    {
        boolean result = false;
        try {
            ColumnParent parent = new ColumnParent(Counter.col_parent);
            ByteBuffer counter_ID = common.GeneralHandling.toByteBuffer(counter.getCounter_ID());
            //Add column vào CF.
            client.insert(counter_ID,parent,GeneralHandling.createCol(Counter.colname_counter, counter.getCounter()),common.Constants.CL);            
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return result;
    }

    
     public static boolean Inscrease(String key, Cassandra.Client cl)
    {
        boolean result = false;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(key);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            ColumnParent parent = new ColumnParent(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            long counter_curr = common.GeneralHandling.toLong(counterCol.value);
            counter_curr += 1;
            cl.insert(rowkey, parent, GeneralHandling.createCol(Counter.colname_counter, common.GeneralHandling.toStringFromLong(counter_curr)), common.Constants.CL);
            result = true;
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }    
    
    public static boolean Decrease(String key, Cassandra.Client cl)
    {
        boolean result = false;
        try {
            ByteBuffer rowkey = common.GeneralHandling.toByteBuffer(key);
            ColumnPath path = new ColumnPath(Counter.col_parent);
            ColumnParent parent = new ColumnParent(Counter.col_parent);
            
            path.column = common.GeneralHandling.toByteBuffer(Counter.colname_counter);
            ColumnOrSuperColumn counter = cl.get(rowkey, path, common.Constants.CL);
            
            Column counterCol = counter.column;
            long counter_curr = common.GeneralHandling.toLong(counterCol.value);
            counter_curr -= 1;
            cl.insert(rowkey, parent, GeneralHandling.createCol(Counter.colname_counter, common.GeneralHandling.toStringFromLong(counter_curr)), common.Constants.CL);
            result = true;
        
        } catch (NotFoundException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidRequestException ex) {
            Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
    
    public void setCounterStatusGlobal()
    {
        try {
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Status.colname_createdate));
            
            ColumnParent parent = new ColumnParent(Status.col_parent);
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = Short.MAX_VALUE;
            List<KeySlice> results = client.get_range_slices(parent, predicate, range, common.Constants.CL);       
            Counter c = new Counter(Counter.key_status, Integer.toString(results.size()));
            setCounter(c);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        }       
    }

    public void setCounterTagGlobal()
    {
        try {
            
            SlicePredicate predicate = new SlicePredicate();
            predicate.addToColumn_names(common.GeneralHandling.toByteBuffer(Tag.name_col_cdate));
                    
            ColumnParent parent = new ColumnParent(Tag.col_parent);
            KeyRange range = new KeyRange();
            range.start_key = common.GeneralHandling.toByteBuffer("");
            range.end_key = common.GeneralHandling.toByteBuffer("");
            range.count = Short.MAX_VALUE;
            List<KeySlice> results = client.get_range_slices(parent, predicate, range, common.Constants.CL);
            Counter c = new Counter(Counter.key_tag, Integer.toString(results.size()));
            setCounter(c);
            
        } catch (InvalidRequestException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnavailableException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TimedOutException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (UnsupportedEncodingException ex) {
            Logger.getLogger(CounterDAO.class.getName()).log(Level.SEVERE, null, ex);
        }       
    } 
}
